home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 December / Chip Aralık 2001.iso / prog / internet / netscape / browser.xpi / bin / chrome / toolkit.jar / content / global / nsTransferable.js < prev    next >
Encoding:
JavaScript  |  2001-07-02  |  9.9 KB  |  289 lines

  1. /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public
  4.  * License Version 1.1 (the "License"); you may not use this file
  5.  * except in compliance with the License. You may obtain a copy of
  6.  * the License at http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the License is distributed on an "AS
  9.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  10.  * implied. See the License for the specific language governing
  11.  * rights and limitations under the License.
  12.  *
  13.  * The Original Code is mozilla.org code.
  14.  *
  15.  * The Initial Developer of the Original Code is Netscape
  16.  * Communications Corporation.  Portions created by Netscape are
  17.  * Copyright (C) 1998 Netscape Communications Corporation. All
  18.  * Rights Reserved.
  19.  *
  20.  * Contributor(s): 
  21.  *   Ben Goodger <ben@netscape.com> (Original Author)
  22.  */
  23.  
  24. ////////////////////////////////////////////////////////////////////////////
  25. // XXX - WARNING - DRAG AND DROP API CHANGE ALERT - XXX
  26. // This file has been extensively modified in a checkin planned for Mozilla
  27. // 0.8, and the API has been modified. DO NOT MODIFY THIS FILE without 
  28. // approval from ben@netscape.com, otherwise your changes will be lost. 
  29.  
  30. /** 
  31.  *  nsTransferable - a wrapper for nsITransferable that simplifies
  32.  *                   javascript clipboard and drag&drop. for use in
  33.  *                   these situations you should use the nsClipboard
  34.  *                   and nsDragAndDrop wrappers for more convenience
  35.  **/ 
  36.  
  37. var nsTransferable = {
  38.   /**
  39.    * nsITransferable set (TransferData aTransferData) ;
  40.    *
  41.    * Creates a transferable with data for a list of supported types ("flavours")
  42.    * 
  43.    * @param TransferData aTransferData
  44.    *        a javascript object in the format described above 
  45.    **/ 
  46.   set: function (aTransferDataSet)
  47.     {
  48.       var trans = this.createTransferable();
  49.       for (var i = 0; i < aTransferDataSet.dataList.length; ++i) 
  50.         {
  51.           var currData = aTransferDataSet.dataList[i];
  52.           var currFlavour = currData.flavour.contentType;
  53.           trans.addDataFlavor(currFlavour);
  54.           var supports = null; // nsISupports data
  55.           var length = 0;
  56.           if (currData.flavour.dataIIDKey == "nsISupportsWString")
  57.             {
  58.               supports = Components.classes["@mozilla.org/supports-wstring;1"]
  59.                                    .createInstance(Components.interfaces.nsISupportsWString);
  60.  
  61.               supports.data = currData.supports;
  62.               length = supports.data.length;
  63.             }
  64.           else 
  65.             {
  66.               // non-string data. TBD!
  67.             }
  68.           trans.setTransferData(currFlavour, supports, length * 2);
  69.         }
  70.       return trans;
  71.     },
  72.   
  73.   /**
  74.    * TransferData/TransferDataSet get (FlavourSet aFlavourSet, 
  75.    *                                   Function aRetrievalFunc, Boolean aAnyFlag) ;
  76.    *
  77.    * Retrieves data from the transferable provided in aRetrievalFunc, formatted
  78.    * for more convenient access.
  79.    *
  80.    * @param FlavourSet aFlavourSet
  81.    *        a FlavourSet object that contains a list of supported flavours.
  82.    * @param Function aRetrievalFunc
  83.    *        a reference to a function that returns a nsISupportsArray of nsITransferables
  84.    *        for each item from the specified source (clipboard/drag&drop etc)
  85.    * @param Boolean aAnyFlag
  86.    *        a flag specifying whether or not a specific flavour is requested. If false,
  87.    *        data of the type of the first flavour in the flavourlist parameter is returned,
  88.    *        otherwise the best flavour supported will be returned.
  89.    **/
  90.   get: function (aFlavourSet, aRetrievalFunc, aAnyFlag)
  91.     {
  92.       if (!aRetrievalFunc) 
  93.         throw "No data retrieval handler provided!";
  94.       
  95.       var supportsArray = aRetrievalFunc(aFlavourSet);
  96.       var dataArray = [];
  97.       var count = supportsArray.Count();
  98.       
  99.       // Iterate over the number of items returned from aRetrievalFunc. For
  100.       // clipboard operations, this is 1, for drag and drop (where multiple
  101.       // items may have been dragged) this could be >1.
  102.       for (var i = 0; i < count; i++)
  103.         {
  104.           var trans = supportsArray.GetElementAt(i);
  105.           if (!trans) continue;
  106.           trans = trans.QueryInterface(Components.interfaces.nsITransferable);
  107.             
  108.           var data = { };
  109.           var length = { };
  110.           
  111.           var currData = null;
  112.           if (aAnyFlag)
  113.             { 
  114.               var flavour = { };
  115.               trans.getAnyTransferData(flavour, data, length);
  116.               if (data && flavour)
  117.                 {
  118.                   var selectedFlavour = aFlavourSet.flavourTable[flavour.value];
  119.                   if (selectedFlavour) 
  120.                     dataArray[i] = FlavourToXfer(data.value, length.value, selectedFlavour);
  121.                 }
  122.             }
  123.           else
  124.             {
  125.               var firstFlavour = aFlavourSet.flavours[0];
  126.               trans.getTransferData(firstFlavour, data, length);
  127.               if (data && firstFlavour)
  128.                 dataArray[i] = FlavourToXfer(data.value, length.value, firstFlavour);
  129.             }
  130.         }
  131.       return new TransferDataSet(dataArray);
  132.     },
  133.  
  134.   /** 
  135.    * nsITransferable createTransferable (void) ;
  136.    *
  137.    * Creates and returns a transferable object.
  138.    **/    
  139.   createTransferable: function ()
  140.     {
  141.       const kXferableContractID = "@mozilla.org/widget/transferable;1";
  142.       const kXferableIID = Components.interfaces.nsITransferable;
  143.       return Components.classes[kXferableContractID].createInstance(kXferableIID);
  144.     }
  145. };  
  146.  
  147. /** 
  148.  * A FlavourSet is a simple type that represents a collection of Flavour objects.
  149.  * FlavourSet is constructed from an array of Flavours, and stores this list as
  150.  * an array and a hashtable. The rationale for the dual storage is as follows:
  151.  * 
  152.  * Array: Ordering is important when adding data flavours to a transferable. 
  153.  *        Flavours added first are deemed to be 'preferred' by the client. 
  154.  * Hash:  Convenient lookup of flavour data using the content type (MIME type)
  155.  *        of data as a key. 
  156.  */
  157. function FlavourSet(aFlavourList)
  158. {
  159.   this.flavours = aFlavourList || [];
  160.   this.flavourTable = { };
  161.  
  162.   this._XferID = "FlavourSet";
  163.   
  164.   for (var i = 0; i < this.flavours.length; ++i)
  165.     this.flavourTable[this.flavours[i].contentType] = this.flavours[i];
  166. }
  167.  
  168. FlavourSet.prototype = {
  169.   appendFlavour: function (aFlavour, aFlavourIIDKey)
  170.   {
  171.     var flavour = new Flavour (aFlavour, aFlavourIIDKey);
  172.     this.flavours.push(flavour);
  173.     this.flavourTable[flavour.contentType] = flavour;
  174.   }
  175. };
  176.  
  177. /** 
  178.  * A Flavour is a simple type that represents a data type that can be handled. 
  179.  * It takes a content type (MIME type) which is used when storing data on the
  180.  * system clipboard/drag and drop, and an IIDKey (string interface name
  181.  * which is used to QI data to an appropriate form. The default interface is
  182.  * assumed to be wide-string.
  183.  */ 
  184. function Flavour(aContentType, aDataIIDKey)
  185. {
  186.   this.contentType = aContentType;
  187.   this.dataIIDKey = aDataIIDKey || "nsISupportsWString";
  188.  
  189.   this._XferID = "Flavour";
  190. }
  191.  
  192. function TransferDataBase() {}
  193. TransferDataBase.prototype = {
  194.   push: function (aItems)
  195.   {
  196.     this.dataList.push(aItems);
  197.   },
  198.  
  199.   get first ()
  200.   {
  201.     return "dataList" in this && this.dataList.length ? this.dataList[0] : null;
  202.   }
  203. };
  204.  
  205. /** 
  206.  * TransferDataSet is a list (array) of TransferData objects, which represents
  207.  * data dragged from one or more elements. 
  208.  */
  209. function TransferDataSet(aTransferDataList)
  210. {
  211.   this.dataList = aTransferDataList || [];
  212.  
  213.   this._XferID = "TransferDataSet";
  214. }
  215. TransferDataSet.prototype = TransferDataBase.prototype;
  216.  
  217. /** 
  218.  * TransferData is a list (array) of FlavourData for all the applicable content
  219.  * types associated with a drag from a single item. 
  220.  */
  221. function TransferData(aFlavourDataList)
  222. {
  223.   this.dataList = aFlavourDataList || [];
  224.  
  225.   this._XferID = "TransferData";
  226. }
  227. TransferData.prototype = {
  228.   __proto__: TransferDataBase.prototype,
  229.   
  230.   addDataForFlavour: function (aFlavourString, aData, aLength, aDataIIDKey)
  231.   {
  232.     this.dataList.push(new FlavourData(aData, aLength, 
  233.                        new Flavour(aFlavourString, aDataIIDKey)));
  234.   }
  235. };
  236.  
  237. /** 
  238.  * FlavourData is a type that represents data retrieved from the system 
  239.  * clipboard or drag and drop. It is constructed internally by the Transferable
  240.  * using the raw (nsISupports) data from the clipboard, the length of the data,
  241.  * and an object of type Flavour representing the type. Clients implementing
  242.  * IDragDropObserver receive an object of this type in their implementation of
  243.  * onDrop. They access the 'data' property to retrieve data, which is either data 
  244.  * QI'ed to a usable form, or unicode string. 
  245.  */
  246. function FlavourData(aData, aLength, aFlavour) 
  247. {
  248.   this.supports = aData;
  249.   this.contentLength = aLength;
  250.   this.flavour = aFlavour || null;
  251.   
  252.   this._XferID = "FlavourData";
  253. }
  254.  
  255. FlavourData.prototype = {
  256.   get data ()
  257.   {
  258.     if (this.flavour && 
  259.         this.flavour.dataIIDKey != "nsISupportsWString" )
  260.       return this.supports.QueryInterface(Components.interfaces[this.flavour.dataIIDKey]); 
  261.     else {
  262.       var unicode = this.supports.QueryInterface(Components.interfaces.nsISupportsWString);
  263.       if (unicode) 
  264.         return unicode.data.substring(0, this.contentLength/2);
  265.      
  266.       return this.supports;
  267.     }
  268.     return "";
  269.   }
  270. }
  271.  
  272. /** 
  273.  * Create a TransferData object with a single FlavourData entry. Used when 
  274.  * unwrapping data of a specific flavour from the drag service. 
  275.  */
  276. function FlavourToXfer(aData, aLength, aFlavour) 
  277. {
  278.   return new TransferData([new FlavourData(aData, aLength, aFlavour)]);
  279. }
  280.  
  281. /*
  282. function DUMP_obj (aObj) 
  283. {
  284.   for (var i in aObj)
  285.     dump("*** aObj[" + i + "] = " + aObj[i] + "\n");
  286. }
  287. */
  288.  
  289.